Fix domain death to stop all CPUs running over the defunct page tables.
struct pfn_info *page;
unsigned long x, y;
- /*
- * If we're executing the idle task then we may still be running over the
- * dead domain's page tables. We'd better fix that before freeing them!
- */
- if ( is_idle_task(current) )
- write_ptbase(¤t->mm);
+ /* Ensure that noone is running over the dead domain's page tables. */
+ synchronise_pagetables(~0UL);
/* Exit shadow mode before deconstructing final guest page table. */
shadow_mode_disable(d);
}
+/*
+ * Allows shooting down of borrowed page-table use on specific CPUs.
+ * Specifically, we borrow page tables when running the idle domain.
+ */
+static void __synchronise_pagetables(void *mask)
+{
+ struct domain *d = current;
+ if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) )
+ write_ptbase(&d->mm);
+}
+void synchronise_pagetables(unsigned long cpu_mask)
+{
+ __synchronise_pagetables((void *)cpu_mask);
+ smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1);
+}
+
long do_stack_switch(unsigned long ss, unsigned long esp)
{
int nr = smp_processor_id();
init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
-
#elif defined(__x86_64__)
init_frametable(__va(xenheap_phys_end), max_page);
int check_descriptor(unsigned long a, unsigned long b);
+/*
+ * Use currently-executing domain's pagetables on the specified CPUs.
+ * i.e., stop borrowing someone else's tables if you are the idle domain.
+ */
+void synchronise_pagetables(unsigned long cpu_mask);
+
/*
* The MPT (machine->physical mapping table) is an array of word-sized
* values, indexed on machine frame number. It is expected that guest OSes